#!/bin/bash

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd "$DIR/../../"

tmpfile="$DIR/cppcheck_and_clang_format.tmp"
errfile="$DIR/cppcheck_and_clang_format.txt"

mode=${1:-diff}
threads=$( cat /proc/cpuinfo | grep processor | wc -l )

if [ "$mode" == diff ]; then
    files=$( git diff --name-only HEAD~1 HEAD | egrep '^(src|tests|poc)' | egrep '\.(hpp|h|cpp)$' )
    flags=""
else
    files=src/
    flags="-j$threads -Isrc"
fi

cat > .cppcheck_suppressions <<EOF
// supress all explicit constructor warnings since we use the implicit conversion all over the codebase
noExplicitConstructor:src/storage/property_value.hpp
noExplicitConstructor:src/query/typed_value.hpp
noExplicitConstructor:src/communication/bolt/v1/decoder/decoded_value.hpp

// suppress antlr warnings
variableScope:src/query/frontend/opencypher/generated/CypherParser.h
variableScope:src/query/frontend/opencypher/generated/CypherLexer.h
variableScope:src/query/frontend/opencypher/generated/CypherParser.cpp

// supress all warnings of this type in the codebase
missingInclude
unusedFunction
unusedStructMember
useStlAlgorithm
EOF

cppcheck --enable=all --inline-suppr --force --suppressions-list=.cppcheck_suppressions $flags $files 2>"$tmpfile"
rm .cppcheck_suppressions

cat "$tmpfile" | grep -v "(information) Unmatched suppression" > "$errfile"
rm $tmpfile

cat "$errfile" >&2

len="$( cat "$errfile" | wc -l )"
if [ $len -gt 0 ]; then
    echo -e "==== Cppcheck errors: ====\n\n\`\`\`\n$( cat "$errfile" )\n\`\`\`" > "$errfile"
fi


# check for clang-format errors

format_list=""
format_tmp="$DIR/.clang_format"

if [ -f "$format_tmp" ]; then
    rm "$format_tmp"
fi

for fname in $files; do
    if [ ! -f "$fname" ]; then continue; fi
    echo "Checking formatting errors for: $fname"
    clang-format "$fname" > "$format_tmp"
    if ! diff "$fname" "$format_tmp" >/dev/null; then
        format_list+="\n$fname"
    fi
    rm "$format_tmp"
done

if [ "$format_list" != "" ]; then
    if [ "$( cat "$errfile" | wc -l )" -gt 0 ]; then
        echo "" >> "$errfile"
    fi
    echo -e "==== Clang-format should be applied on: ====\n\n\`\`\`$format_list\n\`\`\`" >> "$errfile"
fi
